module KEY_scan
(
	input clk_in_50m,
	input rst_n,
	input key_1,
	input key_2,
	input key_3,
	input key_4,
	
	output [31:0] fre_word_out
);

//10m: 429496730  1k: 42950  100: 4295
parameter FRE_WORD_INIT = FRE_WORD_MIN;
parameter FRE_WORD_MIN = 32'd42950;
parameter FRE_WORD_MAX = 32'd429496730;
parameter FRE_WORD_STEP = 32'd4295;
parameter time_delay_cnt = 20'hF4240;//20 ms ~ 50m Hz

/* wire define */
wire key_1_flip_reslt;
wire key_1_scan_reslt;
wire key_2_flip_reslt;
wire key_2_scan_reslt;
wire key_3_flip_reslt;
wire key_3_scan_reslt;

/* reg define */
reg [31:0] fre_word;

reg key_1_flip_now;
reg key_1_flip_prev;
reg key_1_scan_now;
reg key_1_scan_prev;
reg [19:0] key_1_delay_cnt;
reg key_2_flip_now;
reg key_2_flip_prev;
reg key_2_scan_now;
reg key_2_scan_prev;
reg [19:0] key_2_delay_cnt;
reg key_3_flip_now;
reg key_3_flip_prev;
reg key_3_scan_now;
reg key_3_scan_prev;
reg [19:0] key_3_delay_cnt;

/* key1 */

always @(posedge clk_in_50m or negedge rst_n)
begin
	if(rst_n == 0)
	begin
		key_1_flip_now <= 1'b1;
	end
	else
	begin
		key_1_flip_now <= key_1;
	end
end

always @(posedge clk_in_50m or negedge rst_n)
begin
	if(rst_n == 0)
	begin
		key_1_flip_prev <= 1'b1;
	end
	else
	begin
		key_1_flip_prev <= key_1_flip_now;
	end	
end

//key_1_flip_reslt==1: 按键下降沿
assign key_1_flip_reslt = key_1_flip_prev & (~key_1_flip_now);

/* 20ms延时 */
always @(posedge clk_in_50m or negedge rst_n)
begin
	if(rst_n == 0)
		key_1_delay_cnt <= 20'h0;
	else if(key_1_flip_reslt)
		key_1_delay_cnt <= 20'h0;
	else 
		key_1_delay_cnt <= key_1_delay_cnt + 1'b1;
end

/* 20ms延时后再次检测 */
always @(posedge clk_in_50m or negedge rst_n)
begin
	if(rst_n == 0)
		key_1_scan_now <= 1'b1;
	else if(key_1_delay_cnt == time_delay_cnt)
	begin
		key_1_scan_now <= key_1;
	end	
end

always @(posedge clk_in_50m or negedge rst_n)
begin
	if(rst_n == 0)
		key_1_scan_prev <= 1'b1;
	else
	begin
		key_1_scan_prev <= key_1_scan_now;
	end	
end

assign key_1_scan_reslt = key_1_scan_prev & (~key_1_scan_now);

/* key2 */

always @(posedge clk_in_50m or negedge rst_n)
begin
	if(rst_n == 0)
	begin
		key_2_flip_now <= 1'b1;
	end
	else
	begin
		key_2_flip_now <= key_2;
	end
end

always @(posedge clk_in_50m or negedge rst_n)
begin
	if(rst_n == 0)
	begin
		key_2_flip_prev <= 1'b1;
	end
	else
	begin
		key_2_flip_prev <= key_2_flip_now;
	end
end

//key_2_flip_reslt==1: 按键下降沿
assign key_2_flip_reslt = key_2_flip_prev & (~key_2_flip_now);

/* 20ms延时 */
always @(posedge clk_in_50m or negedge rst_n)
begin
	if(rst_n == 0)
		key_2_delay_cnt <= 20'h0;
	else if(key_2_flip_reslt)
		key_2_delay_cnt <= 20'h0;
	else 
		key_2_delay_cnt <= key_2_delay_cnt + 1'b1;
end

/* 20ms延时后再次检测 */
always @(posedge clk_in_50m or negedge rst_n)
begin
	if(rst_n == 0)
		key_2_scan_now <= 1'b1;
	else if(key_2_delay_cnt == time_delay_cnt)
	begin
		key_2_scan_now <= key_2;
	end	
end

always @(posedge clk_in_50m or negedge rst_n)
begin
	if(rst_n == 0)
		key_2_scan_prev <= 1'b1;
	else
	begin
		key_2_scan_prev <= key_2_scan_now;
	end	
end

assign key_2_scan_reslt = key_2_scan_prev & (~key_2_scan_now);

/* key3 */

always @(posedge clk_in_50m or negedge rst_n)
begin
	if(rst_n == 0)
	begin
		key_3_flip_now <= 1'b1;
	end
	else
	begin
		key_3_flip_now <= key_3;
	end
end

always @(posedge clk_in_50m or negedge rst_n)
begin
	if(rst_n == 0)
	begin
		key_3_flip_prev <= 1'b1;
	end
	else
	begin
		key_3_flip_prev <= key_3_flip_now;
	end
end

//key_3_flip_reslt==1: 按键下降沿
assign key_3_flip_reslt = key_3_flip_prev & (~key_3_flip_now);

/* 20ms延时 */
always @(posedge clk_in_50m or negedge rst_n)
begin
	if(rst_n == 0)
		key_3_delay_cnt <= 20'h0;
	else if(key_3_flip_reslt)
		key_3_delay_cnt <= 20'h0;
	else 
		key_3_delay_cnt <= key_3_delay_cnt + 1'b1;
end

/* 20ms延时后再次检测 */
always @(posedge clk_in_50m or negedge rst_n)
begin
	if(rst_n == 0)
		key_3_scan_now <= 1'b1;
	else if(key_3_delay_cnt == time_delay_cnt)
	begin
		key_3_scan_now <= key_3;
	end	
end

always @(posedge clk_in_50m or negedge rst_n)
begin
	if(rst_n == 0)
		key_3_scan_prev <= 1'b1;
	else
	begin
		key_3_scan_prev <= key_3_scan_now;
	end	
end

assign key_3_scan_reslt = key_3_scan_prev & (~key_3_scan_now);

/* 改变频率字 */
always @(posedge clk_in_50m or negedge rst_n)
begin
	if(rst_n == 0)
		fre_word <= FRE_WORD_INIT;
	else if(key_1_scan_reslt)
	begin
		if(fre_word - FRE_WORD_STEP > FRE_WORD_MIN)
			fre_word <= fre_word - FRE_WORD_STEP;
		else
			fre_word <= FRE_WORD_MIN;
	end
	else if(key_2_scan_reslt)
	begin
		if(fre_word + FRE_WORD_STEP < FRE_WORD_MAX)
			fre_word <= fre_word + FRE_WORD_STEP;
		else
			fre_word <= FRE_WORD_MAX;
	end
	else if(key_3_scan_reslt)
	begin
		fre_word <= FRE_WORD_MAX;
	end
	else
		fre_word <= fre_word;
end

assign fre_word_out = fre_word;

endmodule
